package coop.demanda.habitacional;

import coop.demanda.habitacional.util.JsfUtil;
import coop.demanda.habitacional.util.JsfUtil.PersistAction;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Named;
import org.primefaces.event.FlowEvent;
import org.primefaces.event.TabChangeEvent;
import org.primefaces.event.TabCloseEvent;
import org.primefaces.event.TransferEvent;
import org.primefaces.model.DualListModel;

@Named("demandaHabitacionalController")
@SessionScoped
public class DemandaHabitacionalController implements Serializable {

    @EJB
    private coop.demanda.habitacional.DemandaHabitacionalFacade demandaHabitacionalFacade;

    private List<DemandaHabitacional> items = null;

    @EJB
    private LoginFacade loginFacade;

    private Persona persona = new Persona();

    private List<Persona> grupoFamiliar = new ArrayList<Persona>();

    private boolean skip;

    private boolean mostrar;

    private boolean modo;

    private DemandaHabitacional selected;

    private boolean nuevoIntegrante;

    private boolean habilitar;

    private DualListModel<String> servicios;

    private boolean mostrarBotonGuardar = true;

    /**
     * Get the value of mostrarBotonGuardar
     *
     * @return the value of mostrarBotonGuardar
     */
    public boolean isMostrarBotonGuardar() {
        return mostrarBotonGuardar;
    }

    /**
     * Set the value of mostrarBotonGuardar
     *
     * @param mostrarBotonGuardar new value of mostrarBotonGuardar
     */
    public void setMostrarBotonGuardar(boolean mostrarBotonGuardar) {
        this.mostrarBotonGuardar = mostrarBotonGuardar;
    }

    /**
     * Get the value of nuevoIntegrante
     *
     * @return the value of nuevoIntegrante
     */
    public boolean isNuevoIntegrante() {
        return nuevoIntegrante;
    }

    /**
     * Set the value of nuevoIntegrante
     *
     * @param nuevoIntegrante new value of nuevoIntegrante
     */
    public void setNuevoIntegrante(boolean nuevoIntegrante) {
        this.nuevoIntegrante = nuevoIntegrante;
    }

    /**
     * Get the value of selected
     *
     * @return the value of selected
     */
    public DemandaHabitacional getSelected() {
        return selected;
    }

    /**
     * Set the value of selected
     *
     * @param selected new value of selected
     */
    public void setSelected(DemandaHabitacional selected) {
        this.selected = selected;
    }

    private static Logger logger = Logger.getLogger(DemandaHabitacional.class.getName());

    public DemandaHabitacionalController() {

    }

    public String obtenerNombreDelResponsable() {
        String responsable = null;
        for (Persona p : getGrupoFamiliar()) {
            if (p.isEsResponsable()) {
                responsable = p.getApellido() + ", " + p.getNombre();
            }
        }

        return responsable;
    }

    public String obtenerTelefonoDelResponsable() {
        String tresponsable = null;
        for (Persona p : getGrupoFamiliar()) {
            if (p.isEsResponsable()) {
                tresponsable = p.getTelefono();
            }
        }

        return tresponsable;
    }
    
    
     public String obtenerTelefonoMovilDelResponsable() {
        String tresponsable = null;
        for (Persona p : getGrupoFamiliar()) {
            if (p.isEsResponsable()) {
                tresponsable = p.getTelefonoMovil();
            }
        }

        return tresponsable;
    }

    /**
     * Get the value of modo
     *
     * @return the value of modo
     */
    public boolean getModo() {
        return modo;
    }

    /**
     * Set the value of modo
     *
     * @param modo new value of modo
     */
    public void setModo(boolean modo) {
        this.modo = modo;
    }

    public boolean isSkip() {
        return skip;
    }

    public void setSkip(boolean skip) {
        this.skip = skip;
    }

    public String onFlowProcess(FlowEvent event) {
        setHabilitar(false);
        mostrarOcultar();

//        FacesMessage msg = new FacesMessage("Tab Changed", "Active Tab: " + event.getNewStep());
//        FacesContext.getCurrentInstance().addMessage(null, msg);
        logger.info("Current wizard step:" + event.getOldStep());
        logger.info("Next step:" + event.getNewStep());

        if (!hayUnSoloResponsable()) {
            JsfUtil.addErrorMessage("Es obligatorio ingresar un solicitante. El mismo debe ser único.");
            return event.getOldStep();
        } else if (!hayTelefonoMovil()){
                  JsfUtil.addErrorMessage("El teléfono móvil es requerido");
                  return event.getOldStep();
        }else{
            return event.getNewStep();
        } 
        
//        if ( hayTelefonoMovil() ){
//            return event.getNewStep();
//        }else{
//                JsfUtil.addErrorMessage("El teléfono móvil es requerido");
//                return event.getOldStep();
//        }

    }

    public boolean hayTelefonoMovil() {
//        boolean responsableConMovil = false;
//         for (Persona p : getSelected().getGrupoFamiliar()) {
//            if (!p.getTelefonoMovil().isEmpty() && p.isEsResponsable()) {
//                responsableConMovil = true;
//            }
//        }
//        return responsableConMovil;
          return true;
    }

    public boolean hayUnSoloResponsable() {
        int cantResponsables = 0;

        for (Persona p : grupoFamiliar) {
            if (p.isEsResponsable()) {
                cantResponsables++;
            }
        }

        return cantResponsables == 1;

    }

    protected void setEmbeddableKeys() {
    }

    protected void initializeEmbeddableKey() {
    }

    private DemandaHabitacionalFacade getFacade() {
        return demandaHabitacionalFacade;
    }

    public DemandaHabitacional prepareCreate() {

        this.grupoFamiliar.clear();
        this.persona = new Persona();
        this.servicios.getTarget().clear();

        selected = new DemandaHabitacional();
        FacesContext facesContext = FacesContext.getCurrentInstance();
        Integer ul = (Integer) facesContext.getExternalContext().getSessionMap().get("usuarioLogueadoId");
        Login usuarioLogueado = loginFacade.find(ul);
//       DemandaHabitacional demandaHabitacional = getSelected();
        selected.setUsuario(usuarioLogueado);
        selected.setMunicipio(usuarioLogueado.getMunicipio());

       //demandaHabitacionalFacade.create(selected);
        logger.info("Usuario logueado: " + ul.toString());

        return selected;
    }

    public void create() {
        selected.setNombreDelSolicitante(obtenerNombreDelResponsable());
        selected.setTelefonoDelSolicitante(obtenerTelefonoDelResponsable());
        selected.setTelefonoMovil(obtenerTelefonoMovilDelResponsable());
//       getItems().add(selected);
        selected.setGrupoFamiliar(getGrupoFamiliar());
        selected.getServicios().addAll(getServicios().getTarget());

        persist(PersistAction.CREATE, ResourceBundle.getBundle("/Bundle").getString("DemandaHabitacionalCreated"));
        if (!JsfUtil.isValidationFailed()) {
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }

    public void update() {
        persist(PersistAction.UPDATE, ResourceBundle.getBundle("/Bundle").getString("DemandaHabitacionalUpdated"));
    }

    public void destroy() {
        persist(PersistAction.DELETE, ResourceBundle.getBundle("/Bundle").getString("DemandaHabitacionalDeleted"));
        if (!JsfUtil.isValidationFailed()) {
            setSelected(null); // Remove selection
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }

    /**
     * Retorna todas las demandas habitacionales del usuario logueado. Si el
     * usuario es responsable del municipio retorna todas las demandas
     * habitacionales de todos los usuarios del municipio.
     *
     * @return listado de DemandaHabitacional
     */
    public List<DemandaHabitacional> getItems() {

        if (items == null) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            Integer ul = (Integer) facesContext.getExternalContext().getSessionMap().get("usuarioLogueadoId");
            Login usuarioLogueado = loginFacade.find(ul);
            if (usuarioLogueado.isResponsable()) {
                items = getFacade().findAllByMunicipio(usuarioLogueado);
            } else {
                items = getFacade().findAllByUsuarioId(usuarioLogueado);
            }
        }

        return items;
    }

    private void persist(PersistAction persistAction, String successMessage) {
        if (getSelected() != null) {
            setEmbeddableKeys();
            try {
                if (persistAction != PersistAction.DELETE) {
                    getFacade().edit(getSelected());
                } else {
                    getFacade().remove(getSelected());
                }
                JsfUtil.addSuccessMessage(successMessage);
            } catch (EJBException ex) {
                String msg = "";
                Throwable cause = ex.getCause();
                if (cause != null) {
                    msg = cause.getLocalizedMessage();
                }
                if (msg.length() > 0) {
                    JsfUtil.addErrorMessage(msg);
                } else {
                    JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                }
            } catch (Exception ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
                JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            }
        }
    }

    public DemandaHabitacional getDemandaHabitacional(java.lang.Long id) {
        return getFacade().find(id);
    }

    public List<DemandaHabitacional> getItemsAvailableSelectMany() {
        return getFacade().findAll();
    }

    public List<DemandaHabitacional> getItemsAvailableSelectOne() {
        return getFacade().findAll();
    }

    /**
     * @return the grupoFamiliar
     */
    public List<Persona> getGrupoFamiliar() {
        return grupoFamiliar;
    }

    /**
     * @param grupoFamiliar the grupoFamiliar to set
     */
    public void setGrupoFamiliar(List<Persona> grupoFamiliar) {
        this.grupoFamiliar = grupoFamiliar;
    }

    /**
     * @return the persona
     */
    public Persona getPersona() {
        return persona;
    }

    /**
     * @param persona the persona to set
     */
    public void setPersona(Persona persona) {
        this.persona = persona;
    }

    /**
     * @return the mostrar
     */
    public boolean isMostrar() {
        return mostrar;
    }

    /**
     * @param mostrar the mostrar to set
     */
    public void setMostrar(boolean mostrar) {
        this.mostrar = mostrar;
    }

    /**
     * @return the habilitar
     */
    public boolean isHabilitar() {
        return habilitar;
    }

    /**
     * @param habilitar the habilitar to set
     */
    public void setHabilitar(boolean habilitar) {
        this.habilitar = habilitar;
    }

    @FacesConverter(forClass = DemandaHabitacional.class)
    public static class DemandaHabitacionalControllerConverter implements Converter {

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            DemandaHabitacionalController controller = (DemandaHabitacionalController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "demandaHabitacionalController");
            return controller.getDemandaHabitacional(getKey(value));
        }

        java.lang.Long getKey(String value) {
            java.lang.Long key;
            key = Long.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Long value) {
            StringBuilder sb = new StringBuilder();
            sb.append(value);
            return sb.toString();
        }

        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof DemandaHabitacional) {
                DemandaHabitacional o = (DemandaHabitacional) object;
                return getStringKey(o.getId());
            } else {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "object {0} is of type {1}; expected type: {2}", new Object[]{object, object.getClass().getName(), DemandaHabitacional.class.getName()});
                return null;
            }
        }

    }

    public String reinit() {
        this.persona = new Persona();

        return null;
    }

    public void mostrarOcultar() {
        if (getSelected().getTieneVivienda()) {
            setMostrar(false);
        } else {
            setMostrar(true);
        }

    }

    public void habilitar() {
        setHabilitar(false);
    }

    public void desHabilitar() {
        setHabilitar(true);
    }

    public boolean modoVista() {
        this.modo = false;
        return this.modo;
    }

    public boolean modoEdicion() {
        this.modo = true;
        return this.modo;
    }

    public void onTabChange(TabChangeEvent event) {
        FacesMessage msg = new FacesMessage("Tab Changed", "Active Tab: " + event.getTab().getTitle());
        //FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onTabClose(TabCloseEvent event) {
        FacesMessage msg = new FacesMessage("Tab Closed", "Closed tab: " + event.getTab().getTitle());
        //FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onTransfer(TransferEvent event) {
        StringBuilder builder = new StringBuilder();
        for (Object item : event.getItems()) {
            builder.append(item);
        }

        FacesMessage msg = new FacesMessage();
        msg.setSeverity(FacesMessage.SEVERITY_INFO);
        msg.setSummary("Items Transferred");
        msg.setDetail(builder.toString());

        //FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    @PostConstruct
    public void init() {

        List<String> serviciosSource = new ArrayList<String>();
        List<String> serviciosTarget = new ArrayList<String>();

        serviciosSource.add("Gas");
        serviciosSource.add("Agua potable");
        serviciosSource.add("Electricidad");
        serviciosSource.add("Pozo absorbente");
        serviciosSource.add("Cloacas");

        setServicios(new DualListModel<String>(serviciosSource, serviciosTarget));

    }

    /**
     * @return the servicios
     */
    public DualListModel<String> getServicios() {
        return servicios;
    }

    /**
     * @param servicios the servicios to set
     */
    public void setServicios(DualListModel<String> servicios) {
        this.servicios = servicios;
    }

}
